//
//  FacadePattern.swift
//  Facade
//  第一种实现方式，隐藏实现体，仅仅暴露出一个getTreasure()接口。
//  Created by LY on 2017/11/1.
//  Copyright © 2017年 DesignPatterns. All rights reserved.
//

import Foundation

enum TreasureType {
    case SHIP,BURIED,SUNKEN
}
class PirateFacade{
    private let map = TreasureMap()
    private let ship = PirateShip()
    private let crew = PirateCrew()
    
    func getTreasure(type:TreasureType) -> Int?{
        var prizeAmount : Int?
        // select the treasure type
        var treasureMapType : TreasureMap.Treasures
        var crewWorkType : PirateCrew.Actions
        switch type {
        case .SHIP:
            treasureMapType = .GALLEON
            crewWorkType = .ATTACK_SHIP
        case .BURIED:
            treasureMapType = .BURIED_GOLD
            crewWorkType = .DIG_FOR_GLOD
        case .SUNKEN:
            treasureMapType = .SUNKEN_JEWELS
            crewWorkType = .DIVE_FOR_JEWELS
        }
        let treasureLocation = map.findTreasure(type: treasureMapType)
        
        ///convert from map to ship coordinates
        let sequence : [Character] = ["A","B","C","D","E","F","G"]
        let eastWestPos = sequence.index(of: treasureLocation.gridLetter)
        let shipTarget = PirateShip.ShipLocation(NorthSouth: Int(treasureLocation.gridNumber), EastWest: eastWestPos!)
        
        let semaphore = DispatchSemaphore(value: 0)
        
        //relocate ship
        ship.moveToLocation(location: shipTarget) { (location) in
            self.crew.preformAction(action: crewWorkType, callback: { (prize) in
                prizeAmount = prize
                semaphore.signal()
            })
        }
        semaphore.wait()
        return prizeAmount
    }
}

class TransparentFacade {
    let map = TreasureMap()
    let ship = PirateShip()
    let crew = PirateCrew()
    
    func getTreasure(type:TreasureType) -> Int?{
        var prizeAmount:Int?
        var treasureMapType:TreasureMap.Treasures
        var treasureWorkType:PirateCrew.Actions
        switch type {
        case .SHIP:
            treasureMapType = .GALLEON
            treasureWorkType = .ATTACK_SHIP
        case .BURIED:
            treasureMapType = .BURIED_GOLD
            treasureWorkType = .DIG_FOR_GLOD
        case .SUNKEN:
            treasureMapType = .SUNKEN_JEWELS
            treasureWorkType = .DIVE_FOR_JEWELS
        }
        let treasureLocation = map.findTreasure(type: treasureMapType)
        
        let sequence : [Character] = ["A","B","C","D","E","F","G"]
        let eastWestPos = sequence.index(of: treasureLocation.gridLetter)
        let shipTarget = PirateShip.ShipLocation(NorthSouth: Int(treasureLocation.gridNumber), EastWest: eastWestPos!)
        let semaphore = DispatchSemaphore(value: 0)
        ship.moveToLocation(location:shipTarget) { (location) in
            self.crew.preformAction(action: treasureWorkType, callback: { (prize) in
                prizeAmount = prize
                semaphore.signal()
            })
        }
        semaphore.wait()
        return prizeAmount
    }
}
